package com.example.backend.service;

import com.example.backend.domain.entity.Comment;
import com.example.backend.domain.entity.Ticket;
import com.example.backend.domain.entity.User;
import com.example.backend.domain.enums.Role;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 数据权限服务
 * 提供统一的数据权限判断逻辑
 */
@Service
public class DataPermissionService {
    
    /**
     * 判断用户是否可以访问指定工单
     * @param ticket 工单
     * @param user 用户
     * @return true如果有权限访问
     */
    public boolean canAccessTicket(Ticket ticket, User user) {
        if (ticket == null || user == null) {
            return false;
        }
        
        Role role = user.getRole();
        Long userId = user.getId();
        
        return switch (role) {
            case ADMIN -> true; // 管理员可以访问所有工单
            
            case CUSTOMER -> {
                // 客户只能访问自己创建的工单
                User customer = ticket.getCustomer();
                yield customer != null && customer.getId().equals(userId);
            }
            
            case AGENT -> {
                // 客服只能访问分配给自己的工单
                User assignedTo = ticket.getAssignedTo();
                yield assignedTo != null && assignedTo.getId().equals(userId);
            }
            
            case SUPERVISOR -> {
                // 主管可以访问分配给自己的工单
                // 注意：当前不支持团队数据共享，因为User实体没有team字段
                User assignedTo = ticket.getAssignedTo();
                yield assignedTo != null && assignedTo.getId().equals(userId);
            }
            
            case READONLY -> {
                // 只读用户只能访问公开的工单
                Boolean isPublic = ticket.getIsPublic();
                yield isPublic != null && isPublic;
            }
            
            default -> false;
        };
    }
    
    /**
     * 判断用户是否可以修改指定工单
     * @param ticket 工单
     * @param user 用户
     * @return true如果有权限修改
     */
    public boolean canModifyTicket(Ticket ticket, User user) {
        if (ticket == null || user == null) {
            return false;
        }
        
        Role role = user.getRole();
        Long userId = user.getId();
        
        return switch (role) {
            case ADMIN, SUPERVISOR -> true; // 管理员和主管可以修改所有工单
            
            case AGENT -> {
                // 客服只能修改分配给自己的工单
                User assignedTo = ticket.getAssignedTo();
                yield assignedTo != null && assignedTo.getId().equals(userId);
            }
            
            case CUSTOMER -> {
                // 客户只能修改自己创建的工单（通常只能修改特定字段）
                User customer = ticket.getCustomer();
                yield customer != null && customer.getId().equals(userId);
            }
            
            default -> false;
        };
    }
    
    /**
     * 判断用户是否可以删除指定工单
     * @param ticket 工单
     * @param user 用户
     * @return true如果有权限删除
     */
    public boolean canDeleteTicket(Ticket ticket, User user) {
        if (ticket == null || user == null) {
            return false;
        }
        
        // 只有管理员可以删除工单
        return user.getRole() == Role.ADMIN;
    }
    
    /**
     * 判断用户是否可以分配工单
     * @param user 用户
     * @return true如果有权限分配工单
     */
    public boolean canAssignTicket(User user) {
        if (user == null) {
            return false;
        }
        
        Role role = user.getRole();
        return role == Role.ADMIN || role == Role.SUPERVISOR || role == Role.AGENT;
    }
    
    /**
     * 过滤工单列表，只返回用户有权限访问的工单
     * @param tickets 工单列表
     * @param user 用户
     * @return 过滤后的工单列表
     */
    public List<Ticket> filterTicketsByPermission(List<Ticket> tickets, User user) {
        if (tickets == null || user == null) {
            return List.of();
        }
        
        // 管理员可以访问所有工单，直接返回
        if (user.getRole() == Role.ADMIN) {
            return tickets;
        }
        
        return tickets.stream()
                .filter(ticket -> canAccessTicket(ticket, user))
                .collect(Collectors.toList());
    }
    
    /**
     * 判断用户是否可以访问指定评论
     * @param comment 评论
     * @param user 用户
     * @return true如果有权限访问
     */
    public boolean canAccessComment(Comment comment, User user) {
        if (comment == null || user == null) {
            return false;
        }
        
        // 首先检查是否有权限访问该评论所属的工单
        Ticket ticket = comment.getTicket();
        if (ticket == null || !canAccessTicket(ticket, user)) {
            return false;
        }
        
        Role role = user.getRole();
        Long userId = user.getId();
        
        return switch (role) {
            case ADMIN, SUPERVISOR -> true; // 管理员和主管可以访问所有评论
            
            case AGENT, CUSTOMER -> {
                // 客服和客户可以访问自己的评论，或工单相关的公开评论
                User author = comment.getAuthor();
                Boolean isInternal = comment.getIsInternal();
                
                // 自己的评论可以访问
                if (author != null && author.getId().equals(userId)) {
                    yield true;
                }
                
                // 公开评论可以访问
                yield isInternal == null || !isInternal;
            }
            
            case READONLY -> {
                // 只读用户只能访问公开评论
                Boolean isInternal = comment.getIsInternal();
                yield isInternal == null || !isInternal;
            }
            
            default -> false;
        };
    }
    
    /**
     * 判断用户是否可以修改指定评论
     * @param comment 评论
     * @param user 用户
     * @return true如果有权限修改
     */
    public boolean canModifyComment(Comment comment, User user) {
        if (comment == null || user == null) {
            return false;
        }
        
        Role role = user.getRole();
        Long userId = user.getId();
        
        return switch (role) {
            case ADMIN, SUPERVISOR -> true; // 管理员和主管可以修改所有评论
            
            case AGENT, CUSTOMER -> {
                // 只能修改自己的评论
                User author = comment.getAuthor();
                yield author != null && author.getId().equals(userId);
            }
            
            default -> false;
        };
    }
    
    /**
     * 获取数据权限描述（用于调试和日志）
     * @param user 用户
     * @return 权限描述字符串
     */
    public String getPermissionDescription(User user) {
        if (user == null) {
            return "无权限（用户为空）";
        }
        
        Role role = user.getRole();
        
        return switch (role) {
            case ADMIN -> "管理员：可以访问所有数据";
            case CUSTOMER -> "客户：只能访问自己创建的工单";
            case AGENT -> "客服：只能访问分配给自己的工单";
            case SUPERVISOR -> "主管：可以访问分配给自己的工单";
            case READONLY -> "只读用户：只能访问公开的数据";
            default -> "未知角色：无权限";
        };
    }
}

